/*
 * @Descripttion: 工具集
 * @version: 1.1
 * @LastEditors: sakuya
 * @LastEditTime: 2021年7月20日10:58:41
 */

import CryptoJS from 'crypto-js';
import dayjs from 'dayjs';

const tool = {}

/* localStorage */
tool.data = {
	set(table, settings) {
		var _set = JSON.stringify(settings)
		return localStorage.setItem(table, _set);
	},
	get(table) {
		var data = localStorage.getItem(table);
		try {
			data = JSON.parse(data)
		} catch (err) {
			return null
		}
		return data;
	},
	remove(table) {
		return localStorage.removeItem(table);
	},
	clear() {
		return localStorage.clear();
	}
}

/*sessionStorage*/
tool.session = {
	set(table, settings) {
		var _set = JSON.stringify(settings)
		return sessionStorage.setItem(table, _set);
	},
	get(table) {
		var data = sessionStorage.getItem(table);
		try {
			data = JSON.parse(data)
		} catch (err) {
			return null
		}
		return data;
	},
	remove(table) {
		return sessionStorage.removeItem(table);
	},
	clear() {
		return sessionStorage.clear();
	}
}

/* Fullscreen */
tool.screen = function (element) {
	var isFull = !!(document.webkitIsFullScreen || document.mozFullScreen || document.msFullscreenElement || document.fullscreenElement);
	if (isFull) {
		if (document.exitFullscreen) {
			document.exitFullscreen();
		} else if (document.msExitFullscreen) {
			document.msExitFullscreen();
		} else if (document.mozCancelFullScreen) {
			document.mozCancelFullScreen();
		} else if (document.webkitExitFullscreen) {
			document.webkitExitFullscreen();
		}
	} else {
		if (element.requestFullscreen) {
			element.requestFullscreen();
		} else if (element.msRequestFullscreen) {
			element.msRequestFullscreen();
		} else if (element.mozRequestFullScreen) {
			element.mozRequestFullScreen();
		} else if (element.webkitRequestFullscreen) {
			element.webkitRequestFullscreen();
		}
	}
}

/* 复制对象 */
tool.objCopy = function (obj) {
	return JSON.parse(JSON.stringify(obj));
}

/* 日期格式化 */
tool.dateFormat = function (date, fmt = 'yyyy-MM-dd hh:mm:ss') {
	date = new Date(date)
	var o = {
		"M+": date.getMonth() + 1,                 //月份
		"d+": date.getDate(),                    //日
		"h+": date.getHours(),                   //小时
		"m+": date.getMinutes(),                 //分
		"s+": date.getSeconds(),                 //秒
		"q+": Math.floor((date.getMonth() + 3) / 3), //季度
		"S": date.getMilliseconds()             //毫秒
	};
	if (/(y+)/.test(fmt)) {
		fmt = fmt.replace(RegExp.$1, (date.getFullYear() + "").substr(4 - RegExp.$1.length));
	}
	for (var k in o) {
		if (new RegExp("(" + k + ")").test(fmt)) {
			fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)));
		}
	}
	return fmt;
}

tool.timeToDate = function (time,format = 'YYYY-MM-DD HH:mm:ss') {
	return dayjs(time).format(format)
}

/* 千分符 */
tool.groupSeparator = function (num) {
	num = num + '';
	if (!num.includes('.')) {
		num += '.'
	}
	return num.replace(/(\d)(?=(\d{3})+\.)/g, function ($0, $1) {
		return $1 + ',';
	}).replace(/\.$/, '');
}

/* 常用加解密 */
tool.crypto = {
	//MD5加密
	MD5(data) {
		return CryptoJS.MD5(data).toString()
	},
	//BASE64加解密
	BASE64: {
		encrypt(data) {
			return CryptoJS.enc.Base64.stringify(CryptoJS.enc.Utf8.parse(data))
		},
		decrypt(cipher) {
			return CryptoJS.enc.Base64.parse(cipher).toString(CryptoJS.enc.Utf8)
		}
	},
	//AES加解密
	AES: {
		encrypt(data, secretKey) {
			const result = CryptoJS.AES.encrypt(data, CryptoJS.enc.Utf8.parse(secretKey), {
				mode: CryptoJS.mode.ECB,
				padding: CryptoJS.pad.Pkcs7
			})
			return result.toString()
		},
		decrypt(cipher, secretKey) {
			const result = CryptoJS.AES.decrypt(cipher, CryptoJS.enc.Utf8.parse(secretKey), {
				mode: CryptoJS.mode.ECB,
				padding: CryptoJS.pad.Pkcs7
			})
			return CryptoJS.enc.Utf8.stringify(result);
		}
	}
}

tool.isArray = function (value) {
	if (typeof Array.isArray === "function") {
		return Array.isArray(value);
	} else {
		return Object.prototype.toString.call(value) === "[object Array]";
	}
}

tool.isObject = function (value) {
	return Object.prototype.toString.call(value) === "[object Object]";
}

tool.isNumber = function (value) {
	return !isNaN(Number(value));
}

tool.isFunction = function (value) {
	return typeof value == "function";
}

tool.isString = function (value) {
	return typeof value == "string";
}

tool.isEmpty = function (value) {
	if (tool.isArray(value)) {
		return value.length === 0;
	}

	if (tool.isObject(value)) {
		return Object.keys(value).length === 0;
	}

	return value === "" || value === undefined || value === null;
}
// 地址反转
tool.revisePath = function (path) {
	if (!path) {
		return "";
	}

	if (path[0] == "/") {
		return path;
	} else {
		return `/${path}`;
	}
};
// 排序
tool.orderBy = function (list, key) {
	return list.sort((a, b) => a[key] - b[key]);
}
// 数组转树
tool.deepTree = function (list, parentIdName = "parentId", idName = "id", childrenName = "children") {
	let newList = [];
	let map = {};

	list.forEach((e) => (map[e[idName]] = e));

	list.forEach((e) => {
		const parent = map[e[parentIdName]];

		if (parent) {
			(parent[childrenName] || (parent[childrenName] = [])).push(e);
		} else {
			newList.push(e);
		}
	});

	const fn = (list) => {
		list.map((e) => {
			if (e[childrenName] instanceof Array) {
				e[childrenName] = tool.orderBy(e[childrenName], "orderNum");

				fn(e[childrenName]);
			}
		});
	};

	fn(newList);

	return tool.orderBy(newList, "orderNum");
}
// 树转数组
tool.revDeepTree = function (list = [], parentIdName = "parentId") {
	let d = [];
	let id = 0;

	const deep = (list, parentId) => {
		list.forEach((e) => {
			if (!e.id) {
				e.id = id++;
			}

			e[parentIdName] = parentId;

			d.push(e);

			if (e.children && tool.isArray(e.children)) {
				deep(e.children, e.id);
			}
		});
	};

	deep(list || [], null);

	return d;
}
// 驼峰转中横线 AaBbCc 转 aa-bb-cc
tool.camelCaseToHyphen = function (str) {
	return str.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase();
}
// 中横线转 驼峰 aa-bb-cc 转 aaBbCc
tool.transformStr3 = function (str) {
	var re = /-(\w)/g;
	return str.replace(re, function ($0, $1) {
		return $1.toUpperCase();
	});
}
// 去除前后字符串
tool.trim = function (str, char) {
	if (!str) {
		return "";
	}

	if (!char) {
		return str.replace(/^\s+|\s+$/g, "");
	}

	return str.replace(new RegExp("^" + char + "*"), "").replace(new RegExp(char + "*$"), "");
}
// 转换为组件名称
tool.transformName = function (str) {
	return tool.trim(str,'/').replaceAll('/', "-");
}
// 获取我的菜单
tool.adminGetMyMenu = async function (apiObj) {
	var menu = await apiObj.gdshop.admin.permMenu()
	if (menu.code === 0) {
		// 处理菜单
		const routes = menu.data.menus.filter(e => e.type !== 2).map(e => {
			return {
				id: e.id,
				parentId: e.parent_id,
				path: tool.revisePath(e.router || String(e.id)),
				component: e.view_path,
				type: e.type,
				// name: e.name,
				name: tool.transformName(e.router),
				icon: e.icon,
				orderNum: e.sort,
				isShow: tool.isEmpty(e.is_show) ? true : e.is_show,
				meta: {
					title: e.name,
					icon: e.icon,
					keepAlive: e.keep_alive,
					hidden: e.is_show === 1 ? 0 : 1,
					affix: e.router === '/dashboard' ? 1 : 0,
				},
				children: []
			};
		})
		if (routes.length < 1) {
			return [false, '当前用户无任何菜单权限，请联系系统管理员']
		}
		const menuGroup = tool.deepTree(routes);
		tool.data.set("MENU", menuGroup)
		tool.data.set("PERMISSIONS", menu.data.perms)

		return [true, '获取成功']
	} else {
		return [false, menu.message]
	}
};

tool.getBaseUrl = async function (apiObj) {
	let tmp = tool.data.get("BASE_URL") || "";
	if (tmp) {
		return tmp;
	}
	let res = await apiObj.gdshop.attachment.getBaseUrl()
	if (res.code === 0) {
		tool.data.set("BASE_URL", res.data.base_url);
		return res.data.base_url;
	} else {
		return ''
	}
}

tool.getNumber = (value) => {
	const toFixedNum = Number(value).toFixed(3);
	return value ? toFixedNum.substring(0, toFixedNum.toString().length - 1) : "0.00";
};

tool.getMoneyByMinute = (value) => {
	return tool.getNumber(value / 100);
};

tool.get10KMoneyByMinute = (value) => {
	if (value > 1000000) {
		return tool.getNumber(value / 1000000) + "万";
	} else {
		return tool.getNumber(value / 100);
	}
}


/**
 * 笛卡尔积算法
 * @param array
 * @returns {*|*[]|U}
 */
tool.descartes = (array) => {
	if (array.length < 2) {
		return array[0] || [];
	}

	return [].reduce.call(array, (col, set) => {
		const res = [];
		col.forEach((c) => {
			set.forEach((s) => {
				const t = [].concat(Array.isArray(c) ? c : [c]);
				t.push(s);
				res.push(t);
			});
		});

		return res;
	});
};
/**
 * 生成随机字符串
 */
tool.createUniqueString = () => {
	const timestamp = +new Date() + "";
	const randomNum = parseInt((1 + Math.random()) * 65536) + "";
	return (+(randomNum + timestamp)).toString(32);
};

/**
 * 数组去重
 * @param {Array} arr
 * @returns {Array}
 */
tool.uniqueArr = (arr) => {
	return Array.from(new Set(arr));
};

/**
 * @param {Array} arr1
 * @param {Array} arr2
 * @returns {Array}
 */
tool.diffArary = (arr1, arr2) => {
	arr1 = tool.uniqueArr(arr1);
	arr2 = tool.uniqueArr(arr2);
	return arr1.concat(arr2).filter((arg) => !(arr1.includes(arg) && arr2.includes(arg)));
};

tool.arrayUnique = (arr, _key) => {
	const obj = {};
	return arr.reduce(function (item, next) {
		obj[next[_key]] ? "" : (obj[next[_key]] = true && item.push(next));
		return item;
	}, []);
};

tool.sku = {}
// 计算每个sku后面有多少项
tool.sku.getLevels = (tree) => {
	let level = [];
	for (let i = tree.length - 1; i >= 0; i--) {
		if (tree[i + 1] && tree[i + 1].leaf) {
			level[i] = tree[i + 1].leaf.length * level[i + 1] || 1;
		} else {
			level[i] = 1;
		}
	}
	return level;
}
// 笛卡尔积运算
tool.sku.flatten = (tree, stocks = [], options) => {
	let { optionValue = "id", optionText = "value" } = options || {};
	let result = [];
	let skuLen = 0;
	let stockMap = {}; // 记录已存在的stock的数据
	const level = tool.sku.getLevels(tree);
	if (tree.length === 0) return result;
	tree.forEach((sku) => {
		const { leaf } = sku;
		if (!leaf || leaf.length === 0) return true;
		skuLen = (skuLen || 1) * leaf.length;
	});
	// 根据已有的stocks生成一个map
	stocks.forEach((stock) => {
		let { skus, ...attr } = stock;
		stockMap[skus.map((item) => `${item.k_id}_${item.v_id}`).join("|")] = attr;
	});
	for (let i = 0; i < skuLen; i++) {
		let skus = [];
		let mapKey = [];
		tree.forEach((sku, column) => {
			const { leaf } = sku;
			let item = {};
			if (!leaf || leaf.length === 0) return true;
			if (leaf.length > 1) {
				let row = parseInt(i / level[column], 10) % leaf.length;
				item = tree[column].leaf[row];
			} else {
				item = tree[column].leaf[0];
			}
			if (!sku[optionValue] || !item[optionValue]) return;
			mapKey.push(`${sku[optionValue]}_${item[optionValue]}`);
			skus.push({
				k_id: sku[optionValue],
				k: sku[optionText],
				v_id: item[optionValue],
				v: item[optionText]
			});
		});
		let { ...data } = stockMap[mapKey.join("|")] || {};
		// 从map中找出存在的sku并保留其值
		result.push({ ...data, skus });
	}
	return result;
};
// 判断两个sku是否相同
tool.sku.isEqual = (prevSKU, nextSKU, options) => {
	let { optionValue = "id" } = options || {};
	return (
		nextSKU.length === prevSKU.length &&
		nextSKU.every(({ leaf = [] }, index) => {
			let prevLeaf = prevSKU[index].leaf || [];
			return (
				prevSKU[index][optionValue] === nextSKU[index][optionValue] &&
				leaf.length === prevLeaf.length &&
				leaf.map((item) => item[optionValue]).join(",") ===
				prevLeaf.map((item) => item[optionValue]).join(",")
			);
		})
	);
}

tool.getStatusText = (_status) => {
	if (!_status && _status !== 0) return "";
	_status = _status.toString();
	switch (_status) {
		case "0":
			return "关闭";
		case "1":
			return "待付款";
		case "2":
			return "待备货";
		case "3":
			return "待发货";
		case "4":
			return "待收货";
		case "5":
			return "待评价";
		case "99":
			return "已完成";
	}
	return "";
}
tool.isOrderShowBtn = (_type, _order) => {
	if (!_order.subs) {
		return false;
	}
	if (_type === "close_order") {
		// 如果子订单有售后，不显示关闭订单 按钮
		const tmp = _order.subs.filter((item) => {
			return item.refund_status > 0;
		});
		if (tmp.length > 0) {
			return false;
		}
		return _order.status > 0 && _order.status < 4;
	} else if (_type === "confirm_goods") {
		return _order.status == 2;
	} else if (_type === "send_order") {
		return _order.status == 3;
	} else if (_type === "confirm_order") {
		return _order.status == 4;
	} else {
		return false;
	}
}

export default tool
